﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EA_Application;

namespace AddIn.EA.Framework.Common
{
    /// <summary>
    /// Abstract class that is used as based class for the entire list of elements in the framework.
    /// </summary>
    /// <remarks>This base class encapsulate actions and features common for all object of EA Object Model collections.</remarks>
    /// <typeparam name="T">The type of framework element for list control.</typeparam>
    public abstract class BaseList<T> : List<T>, ISimpleElement where T : IElement 
    {
        #region Constructors
        /// <summary>
        /// Constructor that initialize some properties and child elements.
        /// </summary>
        /// <param name="reference">The EA Object Model collection.</param>
        /// <param name="parent">The parent element.</param>
        public BaseList(EA_Application.Collection reference, IElement parent)
        {
            this.Reference = reference;
            this.Parent = parent;
            this.LoadReference();
        }
        #endregion

        #region Properties
        /// <summary>
        /// The EA Object Model collection.
        /// </summary>
        protected EA_Application.Collection Reference { get; set; }
        /// <summary>
        /// The parent element.
        /// </summary>
        public IElement Parent { get; private set; }
        #endregion

        #region Methods
        /// <summary>
        /// Load all child objects contained into the EA Object Model collection translating for the framework elements.
        /// </summary>
        protected virtual void LoadReference()
        {
            foreach (object child in this.Reference)
            {
                if(Parent != null)
                    this.Add((T)Activator.CreateInstance(typeof(T), child, this.Parent));
                else
                    this.Add((T)Activator.CreateInstance(typeof(T), child));
            }
        }
        /// <summary>
        /// Add new element.
        /// </summary>
        /// <param name="name">The element name.</param>
        /// <returns>The framework element object.</returns>
        public virtual T AddNew(string name)
        {
            return this.AddNew(name, null);
        }
        /// <summary>
        /// Add new element.
        /// </summary>
        /// <param name="name">The element name.</param>
        /// <param name="type">The element type.</param>
        /// <returns>The framework element object.</returns>
        public virtual T AddNew(string name, string type)
        { 
            T item = default(T);

            if (Parent != null)
                item = (T)Activator.CreateInstance(typeof(T), this.Reference.AddNew(name, type), Parent);
            else
                item = (T)Activator.CreateInstance(typeof(T), this.Reference.AddNew(name, type));

            this.Add(item);

            return item;
        }
        /// <summary>
        /// Get a referenced element by name.
        /// </summary>
        /// <param name="name">The name of referenced element.</param>
        /// <returns>The framework element object.</returns>
        public virtual T GetReferenceByName(string name)
        {
            foreach (IElement element in this)
            {
                if (element.Name == name)
                    return (T)element;
            }

            return default(T);
        }
        //// <summary>
        /// Get a referenced element by id.
        /// </summary>
        /// <param name="name">The id of referenced element.</param>
        /// <returns>The framework element object.</returns>
        public virtual T GetReferenceById(int id)
        {
            foreach (IElement element in this)
            {
                if (element.ID == id)
                    return (T)element;
            }

            return default(T);
        }
        /// <summary>
        /// Refresh the list of elements into the Project Browser of EA.
        /// </summary>
        public virtual void Refresh()
        {
            foreach (IElement element in this)
                element.Update();

            this.Reference.Refresh();
        }
        #endregion
    }
}
